package com.kingbook.core.generator;

import com.kingbook.common.utils.NumberUtils;
import com.kingbook.common.utils.StringUtils;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Set;

/**
 * @Author: Bucky
 * @Date: 2019/1/2
 * @Version 1.0
 */
public class JavaEntityClassGenerator extends Generator {

    private static final Logger logger = LoggerFactory.getLogger(JavaEntityClassGenerator.class);

    private String target;

    private String packages;

    private List<TableBean> tables;

    private AnnotationInfo info;

    JavaEntityClassGenerator(String target, String packages, List<TableBean> tables, AnnotationInfo info, boolean overWrite) {
        this.target = target + "/" + packages.replace(".", "/");
        this.packages = packages;
        this.tables = tables;
        this.info = info;
        setOverWrite(overWrite);
    }

    void gen() {
        StringBuilder template;
        Set<String> imports;
        StringBuilder properties;
        StringBuilder getAndSet;
        ColumnBean columnBean;
        for (TableBean bean : tables) {
            if (bean.isCreateJavaBean()) {
                template = new StringBuilder();
                imports = Sets.newTreeSet();
                properties = new StringBuilder();
                getAndSet = new StringBuilder();
                template.append("package ").append(packages).append(";\n\n");
                properties.append("    private static final long serialVersionUID = -").append(NumberUtils.randomLong()).append("L;\n\n");
                for (String p : bean.getColumns().keySet()) {
                    columnBean = bean.getColumns().get(p);
                    imports.add(parseImports(columnBean));
                    properties.append(parseProperties(p, columnBean));
//                    getAndSet.append(parseGetAndSet(p, columnBean));
                }
                template.append("import java.io.Serializable;\n");
                for (String im : imports)
                    template.append(im);
                template.append("\n/**" +
                        "\n * " + bean.getComment() +
                        "\n * " +
                        "\n * @Author " + info.getAuthor() +
                        "\n * @Date " + info.getTime() +
                        "\n * @Version " + info.getVersion() +
                        "\n */" +
                        "\n@lombok.Data");
                template.append("\npublic class ").append(bean.getObjectName()).append(" implements Serializable{\n\n");
                template.append(properties);
//                template.append(getAndSet);
                template.append("}");
                writeTemplate(target + "/" + bean.getObjectName() + ".java", template.toString());
            }
        }
    }


    private String parseImports(ColumnBean columnBean) {
        StringBuilder sb = new StringBuilder();
        if (!columnBean.javaType.getFullName().startsWith("java.lang"))
            sb.append("import ").append(columnBean.javaType.getFullName()).append(";\n");
        return sb.toString();
    }

    private String parseProperties(String p, ColumnBean columnBean) {
        p = StringUtils.toCamelCase(p);
        if (StringUtils.isNotEmpty(columnBean.remark))
            return "    /**\n" +
                    "     * " + columnBean.remark + "\n" +
                    "     */\n" +
                    "    private " + columnBean.javaType.getShortName() + " " + p + ";\n\n";
        return "    private " + columnBean.javaType.getShortName() + " " + p + ";\n\n";
    }

    private StringBuilder parseGetAndSet(String p, ColumnBean columnBean) {
        String cp = StringUtils.toCapitalizeCamelUpCase(p);
        p = StringUtils.toCamelCase(p);
        StringBuilder sb = new StringBuilder();
        if ("boolean".endsWith(columnBean.javaType.getShortName())) {
            sb.append("    public boolean is").append(cp).append("() {\n        return ").append(p).append(";\n    }\n\n");
        } else {
            sb.append("    public ").append(columnBean.javaType.getShortName()).append(" get").append(cp).append("() {\n        return ").append(p).append(";\n    }\n\n");
        }
        sb.append("    public void set").append(cp).append("( ").append(columnBean.javaType.getShortName()).append(" ").append(p).append(") {\n        this.").append(p).append(" = ").append(p).append(";\n    }\n\n");
        return sb;
    }
}
